package com.tomatozq163.config;

import com.tomatozq163.receiver.DeviceReceiver;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMQConfig {
    public final static String DELAY_QUEUE_NAME = "delayQueue";
    public final static String DELAY_EXCHANGE_NAME = "delayExchange";
    public final static String DELAY_ROUTE_KEY = "delayKey";

    public final static String NORMAL_QUEUE_NAME = "normalQueue";
    public final static String NORMAL_EXCHANGE_NAME = "normalExchange";
    public final static String NORMAL_ROUTE_KEY = "normalKey";

    @Autowired
    public DeviceReceiver deviceReceiver;

    @Bean
    RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }

    @Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);

        MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(deviceReceiver);
//        messageListenerAdapter.addQueueOrTagToMethodName(queueName, "handleMessage");
//        messageListenerAdapter.setMessageConverter();
        container.setConcurrentConsumers(1);
        container.setMessageListener(messageListenerAdapter);

        return container;
    }

     /**
     * 延迟队列(这个队列不能有接收者，到期没有接收就转到正常队列)
     * @return
     */
    @Bean
    protected Queue delayQueue(){
        return QueueBuilder
                .durable(DELAY_QUEUE_NAME)
                .withArgument("x-dead-letter-exchange", NORMAL_EXCHANGE_NAME)//到期后转发的交换机
                .withArgument("x-dead-letter-routing-key", NORMAL_ROUTE_KEY)   //到期后转发的路由键
                .build();
    }

    /**
     * 延迟交换机
     * @return
     */
    @Bean
    protected DirectExchange delayExchange(){
        //绑定时需要DirectExchange
        return (DirectExchange)ExchangeBuilder
                .directExchange(DELAY_EXCHANGE_NAME)
                .durable(true)
                .build();
    }

    /**
     * 绑定队列与交换机
     * @param delayQueue
     * @param delayExchange
     * @return
     */
    @Bean
    protected Binding delayBinding(Queue delayQueue, DirectExchange delayExchange){
        return BindingBuilder.bind(delayQueue).to(delayExchange).with(DELAY_ROUTE_KEY);
    }

    /**
     * 普通队列
     * @return
     */
    @Bean
    protected Queue normalQueue(){
        return QueueBuilder
                .durable(NORMAL_QUEUE_NAME)
                .build();
    }

    /**
     * 普通交换机
     * @return
     */
    @Bean
    protected DirectExchange normalExchange(){
        //绑定时需要DirectExchange
        return (DirectExchange)ExchangeBuilder
                .directExchange(NORMAL_EXCHANGE_NAME)
                .durable(true)
                .build();
    }

    /**
     * 设备交换机
     * @return
     */
    @Bean
    protected DirectExchange deviceExchange(){
        return (DirectExchange)ExchangeBuilder
                .directExchange("deviceExchange")
                .durable(true)
                .build();
    }

    /**
     * 绑定普通队列和交换机
     * @param normalQueue
     * @param normalExchange
     * @return
     */
    @Bean
    protected Binding normalBinding(Queue normalQueue, DirectExchange normalExchange){
        return BindingBuilder.bind(normalQueue).to(normalExchange).with(NORMAL_ROUTE_KEY);
    }

    /**
     * 订单延迟插件消息队列所绑定的交换机
     */
    @Bean
    CustomExchange  orderPluginDirect() {
        //创建一个自定义交换机，可以发送延迟消息
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange("orderPluginDirect", "x-delayed-message",true, false,args);
    }

    /**
     * 订单延迟插件队列
     */
    @Bean
    public Queue orderPluginQueue() {
        return new Queue("orderPluginQueue");
    }

    /**
     * 将订单延迟插件队列绑定到交换机
     */
    @Bean
    public Binding orderPluginBinding(CustomExchange orderPluginDirect,Queue orderPluginQueue) {
        return BindingBuilder
                .bind(orderPluginQueue)
                .to(orderPluginDirect)
                .with("order")
                .noargs();
    }

    /**
     * 停车信号队列
     * @return
     */
    @Bean
    public Queue vehicleStopQueue(){
        return new Queue("vehicleStopQueue", true);
    }

    @Bean
    CustomExchange vehicleStopExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange("vehicleStopExchange", "x-delayed-message",true, false,args);
//      return new DirectExchange("vehicleStopExchange");
    }

    @Bean
    public Binding vehicleStopBinding(){
        return BindingBuilder
                .bind(vehicleStopQueue())
                .to(vehicleStopExchange())
                .with("vehicleStop")
                .noargs();
    }
}
